package si.unimb.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;

public class StreamManager implements Runnable {

	private Socket socket;
	private DataInputStream in;
	private DataOutputStream out;
	private ServerHost program;
	private ServerListener listner;
	private String nickname;
	private boolean ready;
	private boolean prvic;
	private boolean citaj;
	private boolean dead;
	private int id;
	
	public StreamManager(Socket socket, ServerListener listner, ServerHost program, int id){
		
		this.socket = socket;
		this.listner = listner;
		this.program = program;
		
		setId(id);
		setDead(false);
		setReady(false);
		setCitaj(true);
		setPrvic(true);
		
		try{
			in = new DataInputStream(socket.getInputStream());
			out = new DataOutputStream(socket.getOutputStream());
			sendByte((byte) 0);
			sendMe(id);
		} catch(IOException e){
			e.printStackTrace();
		}
	}

	public void run() {
		while(true){
			try{
				//Game mode
				if(isReady()){
					short id = in.readShort();
					short x = in.readShort();
					short y = in.readShort();
					if(isCitaj()){						
						listner.dataArrived(id, x, y);
						listner.allClientDataArrived();
					}
										
				//Chat mode
				}else{
					int length = in.readInt();
					byte[] b = new byte[length];
					in.readFully(b, 0, length);
					
					if(isPrvic()){
						setNickname(new String(b));
						program.addText("new id: " + getNickname());
						listner.sendAll(new String("New player: " + getNickname()).getBytes());
						setPrvic(false);
					}
					
					String msg = getNickname() + ": " + new String(b);
					program.addText(msg);
					
					commandListner(new String(b));
					
					if(!listner.checkReadyClients())
						listner.sendAll(msg.getBytes());
					else
						setCitaj(true);
				}
			} catch(SocketException e){
				program.addText("Client disconnected! id: " + getNickname());
				listner.removeThread(this);
				closeSocket();
				break;
			} catch(IOException e){
				program.addText("Napaka pri prenosu podatkov!");
				closeSocket();
				break;
			}
		}
	}
	
	public void sendMe(int id){
		String temp = "";
		
		for(int i = 0; i < id; i++)
			temp += "*";
		
		sendString(temp.getBytes());
	}
	
	public void sendString(byte[] b){
		try{
			out.writeInt(b.length);
			out.write(b, 0, b.length);
		} catch (IOException e){
			e.printStackTrace();
		}
	}
	
	public void sendShort(short i){
		try{
			out.writeShort(i);
		}catch(IOException e){}
	}
	
	public void sendByte(byte i){
		try{
			out.writeByte(i);
		}catch(IOException e){}
	}
	
	public void closeSocket(){
		try{
			in.close();
			out.close();
			socket.close();
		} catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public void commandListner(String s){
		s = s.toLowerCase();
		//Client ready
		if(s.equals("/ready"))
			setReady(true);

		if(s.equals("/dead"))
			setDead(true);
		
		if(s.equals("/stopgame"))
			setReady(false);
			
	}
	
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getNickname() {
		return nickname;
	}
	
	public void setReady(boolean ready) {
		this.ready = ready;
	}

	public boolean isReady() {
		return ready;
	}

	public void setCitaj(boolean citaj) {
		this.citaj = citaj;
	}

	public boolean isCitaj() {
		return citaj;
	}

	public void setPrvic(boolean prvic) {
		this.prvic = prvic;
	}

	public boolean isPrvic() {
		return prvic;
	}

	public void setDead(boolean dead) {
		this.dead = dead;
	}

	public boolean isDead() {
		return dead;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}
}
